/*
 * Copyright (C) 2015 soud
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include "erupt.h"
#include "token.h"

token_t *new_token(tokentype type, char *value, size_t start, size_t end, size_t line_n)
{
        token_t *token = smalloc(sizeof(token_t));

        token->type = type;

        token->value  = value;
        token->line_n = line_n;

        token->start = start;
        token->end   = end;

        token->prev = NULL;
        token->next = NULL;

        return token;
}

char *token_value(const char *source, size_t start, size_t end)
{
        char *value = strndup(source+start, end);

        value[end - start] = '\0';

        return value;
}

void dump_tokens(token_t *token)
{
        const char *token_names[] = {
                "plus", "plus_eq", "min", "min_eq", "b_or", "b_or_eq" ,"b_xor",
                "b_xor_eq", "b_and", "b_and_eq", "b_not", "b_not_eq", "l_shift", "r_shift",
                "and", "or", "slash", "slash_eq", "star", "star_eq", "star_star",
                "mod", "mod_eq", "amp", "bang", "lt", "gt", "lteq", "gteq", "eq",
                "eqeq", "noteq", "l_paren", "r_paren", "l_bracket", "r_bracket",
                "l_brace", "r_brace", "dot", "semi_colon", "colon", "ns_sep",
                "r_arrow", "comma", "number", "string", "char", "true", "false",
                "id", "function", "mutable", "if", "unless", "else", "import",
                "return", "for", "while", "break", "continue", "error", "eof"
        };

        do {
                if (token->type < TOKEN_COUNT)
                        printf("(%10s): %s\n", token_names[token->type],
                                               token->value);
                else
                        printf("(?): %s\n", token->value);
        } while ((token = token->next));

        printf("\n");
}

void destroy_tokens(token_t *ts)
{
        if (!ts)
                return;

        do {
                if (ts->value)
                        free(ts->value);

                if (ts->prev)
                        destroy_tokens(ts->prev);
        } while ((ts = ts->next));
}
